package com.hero.take.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.Calendar;
import java.util.Date;

/**
 * @author lipiao
 * @date 2023/3/1/001 11:01
 * @description:
 */
@Slf4j
public class LocalDateUtils {

    public static long toTimes(LocalDateTime localDateTime) {
        return localDateTime.atZone(ZoneId.of("+8")).toInstant().toEpochMilli();
    }

    public static long toTimes(LocalDate localDate) {
        return toTimes(localDate.atTime(0, 0));
    }

    public static LocalDateTime longToLocalDateTime(long times) {
        Date date = new Date(times);
        return LocalDateTime.ofInstant(date.toInstant(), ZoneId.of("+8"));
    }

    public static LocalDate longToLocalDate(long times) {
        return longToLocalDateTime(times).toLocalDate();
    }

    public static LocalDateTime dateToLocalDateTime(Date date) {
        return longToLocalDateTime(date.getTime());
    }

    public static LocalDate dateToLocalDate(Date date) {
        return longToLocalDate(date.getTime());
    }

    public static String formatDate(Date date, String pattern) {
        try {
            SimpleDateFormat format = new SimpleDateFormat(pattern);
            return format.format(date);
        } catch (Exception exception) {
            throw new RuntimeException("格式化日期异常");
        }
    }

    public static String formatDateTime(Date date) {
        return formatDate(date, "yyyy-MM-dd HH:mm:ss");
    }

    public static String formatDate(Date date) {
        return formatDate(date, "yyyy-MM-dd");
    }

    public static String formatLocalDateTime(LocalDateTime localDateTime) {
        return formatDate(new Date(toTimes(localDateTime)));
    }

    public static String formatLocalDate(LocalDate date) {
        return formatDate(new Date(toTimes(date)));
    }

    public static String formatLocalDateTime(LocalDateTime localDateTime, String pattern) {
        return formatDate(new Date(toTimes(localDateTime)), pattern);
    }

    public static String formatLocalDate(LocalDate date, String pattern) {
        return formatDate(new Date(toTimes(date)), pattern);
    }

    public static Date parseDate(String text, String... pattern)  {
        try {
            return DateUtils.parseDate(text, pattern);
        } catch (ParseException e) {
            log.error("日期转换异常:{}",e.getMessage(),e);
            throw new RuntimeException(e.getMessage());
        }
    }

    public static Date parseDate(String text)  {
        return parseDate(text, "yyyy-MM-dd");
    }

    public static Date parseDateTime(String text)  {
        return parseDate(text, "yyyy-MM-dd HH:mm:ss");
    }

    public static LocalDate parseLocalDate(String text, String... pattern)  {
        return dateToLocalDate(parseDate(text, pattern));
    }

    public static LocalDateTime parseLocalDateTime(String text, String... pattern)  {
        return dateToLocalDateTime(parseDate(text, pattern));
    }

    public static LocalDate parseLocalDate(String text) {
        return dateToLocalDate(parseDate(text, "yyyy-MM-dd"));
    }

    public static LocalDateTime parseLocalDateTime(String text) {
        return dateToLocalDateTime(parseDate(text, "yyyy-MM-dd HH:mm:ss"));
    }

    public static Date toDate(LocalDate localDate) {
        if (null == localDate) {
            return null;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zoneId).toInstant();
        return Date.from(instant);
    }

    public static Date toDate(LocalDateTime localDateTime) {
        if (null == localDateTime) {
            return null;
        }
        ZoneId zoneId = ZoneId.systemDefault();
        return Date.from(localDateTime.atZone(zoneId).toInstant());
    }

    public static LocalDate[] getDateRangeOfWeek(){
        return getDateRangeOfWeek(0);
    }
    public static LocalDate[] getDateRangeOfWeek(int idx){
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        LocalDate start = longToLocalDate(calendar.getTimeInMillis());
        calendar.add(Calendar.DAY_OF_WEEK,+7);
        LocalDate end = longToLocalDate(calendar.getTimeInMillis());
        if(idx<0){
            start = start.minusDays(-idx*7);
            end = end.minusDays(-idx*7);
        }else if(idx>0){
            start = start.plusDays(idx*7);
            end = end.plusDays(idx*7);
        }
        return new LocalDate[]{start,end};
    }

    /**
     * LocalDateTime -> Date
     * @param localDateTime
     * @return
     */
    public static Date convertDate(LocalDateTime localDateTime){
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = localDateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }

}
